/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Model;

import java.util.ArrayList;

/**
 *
 * @author Snowangelic
 */
public class Hierarchical extends Clusterization{
    public boolean normalized;
    public Distance distance;
    public ArrayList<Weight> weightList;

    Hierarchical(HierarchicalOptions hOpt){
        Clusterization(hOpt);
        this.weightList=hOpt.getWeightList();
        this.normalized=hOpt.getNormalized();
        this.distance=hOpt.getDistance();
        compute();
    }

    public void compute(){

        Preprocessor prec=new Preprocessor(dataSet);
        prec.normalize();

        ArrayList<Cluster> tempClusList=new ArrayList<Cluster>();
        // --- Step 1 : create one cluster for every action ---
        for (int i=0;i<dataSet.getActionNbr();i++){
            Cluster clus=new Cluster(dataSet);
            clus.setClusterization(this);
            clus.addAction(dataSet.getAction(i));
            clus.recomputePosition();
            tempClusList.add(clus);
        }

        int clusIndex1=0;
        int clusIndex2=0;

        //--- Step 2 : While there is more than the required number of clusters
        // merge the two nearest clusters ---
        while(tempClusList.size()>clusterList.size()){
            float smallestDistance=Float.MAX_VALUE;
            for(int i=0;i<tempClusList.size()-1;i++){
                for(int j=i+1;j<tempClusList.size();j++){
                    float curDist=tempClusList.get(i).getDistance(tempClusList.get(j), weightList, normalized, distance);
                    if(curDist<smallestDistance){
                        smallestDistance=curDist;
                        clusIndex1=i;
                        clusIndex2=j;
                    }
                }
            }
            merge(tempClusList.get(clusIndex1),tempClusList.get(clusIndex2));
            tempClusList.get(clusIndex1).recomputePosition();
            tempClusList.remove(clusIndex2);
        }

        //--- Step 3 : the remaining clusters are saved in the clusterList ---
        for(int i=0;i<clusterList.size();i++){
            clusterList.get(i).setActionList(tempClusList.get(i).getActionList());
            clusterList.get(i).recomputePosition();
        }

    }

    private void merge(Cluster clus1,Cluster clus2){
        ArrayList<Action> actionList=clus2.getActionList();
        for(int i=0;i<actionList.size();i++){
            clus1.addAction(actionList.get(i));
        }
    }


    public ArrayList<Weight> getWeightList() {
        return weightList;
    }

    public Distance getDistance() {
        return distance;
    }

    public boolean getNormalized() {
        return normalized;
    }

    public void AddWeight(Attribute attribute,float weightVal){
        Weight weight=new Weight(attribute,weightVal);
        weightList.add(weight);
    }

}
